/*
 * File name: CCamera.cpp
 * Date:      2010
 * Author:    Tom Krajnik 
 */
#include "CCamera.h"
#include <stdio.h>
#include <stdlib.h>


extern "C" {
#include "utils.h"
#include "color.h"
}

//-----------------------------------------------------------------------------
CCamera::CCamera()
{
	gain = exposition = 0;
	width = height = 0;

	videoIn = (struct vdIn*) calloc(1,sizeof(struct vdIn));
	fprintf(stderr,"Camera strxt cxrated");
	return;
}

CCamera::~CCamera()
{
	close_v4l2(videoIn);
	free(videoIn);
	videoIn = NULL;
	freeLut();
}

int CCamera::init(const char *deviceName)
{
	width = 640;
	height = 480;
	const float fps = 30.0;
	const int format = V4L2_PIX_FMT_YUYV;
	const int grabemethod = 1; 
	char *avifilename = NULL;

	int ret = init_videoIn(videoIn,(char *)deviceName, width,height,fps,format,grabemethod,avifilename);		
	if (ret < 0) {
		fprintf(stderr,"Cannot init camera device: %s\n",deviceName);
		return -1;
	} else {
		fprintf(stderr,"Camera %s initialized\n",deviceName);
	}
	initLut();

	// gets camera parameters
	gain = getDeviceGain();
	exposition = getDeviceExposition();
	brightness = getDeviceBrightness();

	int min,max,def;
	getParamInfo(V4L2_CID_GAIN,min,max,def);
	fprintf(stderr,"Gain parameter: min=%d max=%d default=%d\n",min,max,def);
	getParamInfo(V4L2_CID_BRIGHTNESS,min,max,def);
	fprintf(stderr,"Brightness parameter: min=%d max=%d default=%d\n",min,max,def);
	getParamInfo(V4L2_CID_EXPOSURE,min,max,def);
	fprintf(stderr,"Exposure parameter: min=%d max=%d default=%d\n",min,max,def);

	fprintf(stderr,"Camera gain = %d\n",gain);
	fprintf(stderr,"Camera exposition = %d\n",exposition);
	fprintf(stderr,"Camera brightness = %d\n",brightness);
	return -1;
}




int CCamera::renewImage(CRawImage* image)
{
	int ret = uvcGrab(videoIn);
	if (ret < 0) {
		fprintf(stderr,"Cannot grab a frame from a camera!\n"); 
		return ret;
	}
	fprintf(stderr,"Camera width x height= %d x %d ",videoIn->width,videoIn->height);
	Pyuv422torgb24(videoIn->framebuffer,image->data,videoIn->width,videoIn->height);

	return 0; 
}


int CCamera::getGain()
{
	gain = getDeviceGain();
    return gain;
}

int CCamera::getExposition()
{
	exposition = getDeviceExposition();
	return exposition;
}

int CCamera::getBrightness()
{
	brightness = getDeviceBrightness();
	return brightness;
}

void CCamera::setGain(int value)
{
	gain = value;
	setDeviceGain(value);
}

void CCamera::setExposition(int exp)
{
	exposition = exp;	
	setDeviceExposition(exp);	
}

void CCamera::setBrightness(int val)
{
	brightness = val;
	setDeviceBrightness(val);
}

int CCamera::getDeviceGain() {
	return v4l2GetControl(videoIn,V4L2_CID_GAIN);
}

int CCamera::getDeviceBrightness() {
	return v4l2GetControl(videoIn,V4L2_CID_BRIGHTNESS);
}

int CCamera::getDeviceExposition() {
	return v4l2GetControl(videoIn,V4L2_CID_EXPOSURE);
}

int CCamera::setDeviceExposition(const int value) {
	return v4l2SetControl(videoIn,V4L2_CID_EXPOSURE,value);
}

int CCamera::setDeviceGain(const int value) {
	return v4l2SetControl(videoIn,V4L2_CID_GAIN,value);
}

int CCamera::setDeviceBrightness(const int value) {
	return v4l2SetControl(videoIn,V4L2_CID_BRIGHTNESS,value);
}

int CCamera::getParamInfo(const int paramType, int &min, int &max, int &default_val) 
{
	struct v4l2_queryctrl queryctrl;
	if (isv4l2Control(videoIn,paramType,&queryctrl) < 0) {
		return -1;
	}
	min = queryctrl.minimum;
	max = queryctrl.maximum;
	default_val = queryctrl.default_value;
	return 0;
}

int CCamera::setDeviceAutoExposure(const bool val) {
	struct v4l2_control control;
	control.id = V4L2_CID_EXPOSURE_AUTO;
	control.value =(int)val;
	int ret;
	if ((ret = ioctl(videoIn->fd, VIDIOC_S_CTRL, &control)) < 0) {
		printf("Set Auto Exposure on error\n");
	} else {
		printf("Auto Exposure set to %d\n", control.value);
	}
	return 0;
}


